package com.sm.honkon.ui.fragment.laser_therapy

import android.os.Bundle
import android.view.inputmethod.EditorInfo
import android.widget.SeekBar
import androidx.collection.ArrayMap
import androidx.core.os.bundleOf
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.observe
import au.com.safie.user.app.util.CacheUtil
import com.blankj.utilcode.util.ToastUtils
import com.sm.honkon.R
import com.sm.honkon.app.MyMqttService
import com.sm.honkon.app.base.BaseFragment
import com.sm.honkon.app.event.ReadDataEvent
import com.sm.honkon.app.ext.getTimeFormat
import com.sm.honkon.app.ext.goBackHome
import com.sm.honkon.app.ext.goMannger
import com.sm.honkon.app.utils.CommondData
import com.sm.honkon.app.utils.SerialPortUtil
import com.sm.honkon.data.bean.CommonConfig
import com.sm.honkon.data.bean.ControlLogCatEntity
import com.sm.honkon.data.bean.CustomerEntity
import com.sm.honkon.databinding.FrgLaserTherapyBinding
import com.sm.honkon.ui.activity.MainActivity
import com.sm.honkon.ui.model.MainViewModel
import kotlinx.android.synthetic.main.frg_laser_therapy.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import me.hgj.jetpackmvvm.ext.nav
import me.hgj.jetpackmvvm.ext.util.toJson
import me.hgj.jetpackmvvm.ext.view.notNull
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.*
import kotlin.system.exitProcess

class LaserTherapyFragment : BaseFragment<MainViewModel, FrgLaserTherapyBinding>() {
    override fun layoutId(): Int = R.layout.frg_laser_therapy

    companion object {
        var isControl = false
    }

    private val act by lazy {
        activity as MainActivity
    }

    var step = 0
        set(value) {
            field = value
            mViewModel.canSelectNS.set(step == 1 && config.psOrNs.get() != 0b0001)
            mViewModel.canSelectPS.set(step == 1 && config.psOrNs.get() != 0b0010)
        }

    val config: CommonConfig by lazy {
        CacheUtil.getCommonConfig()
    }

    val errorVolt = arrayOf("倍频电机故障", "预燃板的故障", "氙灯的故障")
    val errorSJ = arrayOf("探头未接故障", "手柄未入收纳盒故障")
    val errorWD = arrayOf("低于下限极限值", "温度过低", "", "温度过高", "高于上限极限值")

    val tiaojiaoshouju: ArrayMap<Int, Int> by lazy {
        ArrayMap<Int, Int>().apply {
            put(0x70, 2)
            put(0x71, 3)
            put(0x72, 4)
            put(0x73, 5)
            put(0x74, 6)
            put(0x75, 7)
            put(0x76, 8)
            put(0x77, 9)
            put(0x78, 10)
        }
    }

    val yunguangshouju: ArrayMap<Int, Int> by lazy {
        ArrayMap<Int, Int>().apply {
            put(0x01, 2)
            put(0x03, 3)
            put(0x02, 4)
            put(0x06, 5)
            put(0x04, 6)
            put(0x05, 7)
            put(0x07, 8)
            put(0x0F, 9)
            put(0x0E, 10)
        }
    }

    var goBackHome = false

    override fun initView(savedInstanceState: Bundle?) {
        EventBus.getDefault().register(this)
        SerialPortUtil.sendSerialPort(
            CommondData.getInstance()
                .makeTemplate(config.maxTemp.get() * 10, config.minTemp.get() * 10)
        )
        isControl = true
        act.curHandlerEntity.value?.let {
            mViewModel.handlername.set(it.name)
        }
        act.controlLogCat.value?.let {
            mViewModel.controlLogCat.value = it
            mViewModel.light.value = it.pinglv.toIntOrNull() ?: 1
            mViewModel.selectPS.set(it.bochang.toIntOrNull() == 1064)
        }

        mViewModel.canSelectPS.set(config.psOrNs.get() != 0b0010)
        mViewModel.canSelectNS.set(config.psOrNs.get() != 0b0001)
        mViewModel.selectPS.set(mViewModel.canSelectPS.get())
        mViewModel.timeText.set(config.getDefTimeTitle(mViewModel.selectPS.get()))
        mDatabind.model = mViewModel
        mDatabind.click = Click()
        sb_chuguangpinglv.configBuilder
            .max(config.getRealHighestHz().toFloat())
            .sectionCount(config.getRealHighestHz() - 1)
            .build()
        et_dancijishu_num.setOnEditorActionListener { v, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                et_dancijishu_num.isVisible = false
                tv_dancijishu_num.isVisible = true
                mViewModel.count = (
                        et_dancijishu_num.text.toString().trim().toIntOrNull() ?: 20000
                        )
                mViewModel.runCount.set(mViewModel.count)
                return@setOnEditorActionListener true
            }
            false
        }

        seek_bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                seekBar?.progress?.let {
                    SerialPortUtil.sendSerialPort(CommondData.getInstance().makeHonemiao(it))
                }
            }
        })
    }

    override fun onDestroyView() {
        EventBus.getDefault().unregister(this)
        super.onDestroyView()
        isControl = false
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onDataRead(event: ReadDataEvent){
        event.data.let {
            if (isVisible.not()) {
                ToastUtils.showShort("isNotVisible")
                return
            }
            if (it[0].and(0xFF) != 0x01) {
                ToastUtils.showShort("unKnow")
                return
            }
            val type = it[1].and(0xFF)
            val result = it[3].and(0xff)
            when (type) {
                0xC3 -> {
                    mViewModel.runCount.apply {
                        val count = getCount(it)
                        mViewModel.controlLogCat.value?.count = count
                        set(mViewModel.count.minus(count).coerceAtLeast(0))
                        if (mViewModel.isCountDown.get().and(get() <= 0)) {
                            ToastUtils.showShort("次数已用完")
                            stopRun()
                        }
                    }
                }
                0x11 -> {
                    if (result != 0x00) {
                        ToastUtils.showShort("已断开")
                        if (!goBackHome)
                            nav().navigateUp()
                        else
                            nav().goBackHome()
                    } else {
                    }
                }
                //预燃
                0x55 -> {
                    mViewModel.isYuran.set(result == 0x55)
                    when (result) {
                        0x66 -> {
                            stop()
                        }
                        0x00 -> {
                            finishStop()
                        }
                        0x55, 0x77 -> {
                            yuran()
                            mViewModel.errorHint.set("")
                        }
                        else -> {
                        }
                    }
                }
                0x66 -> {
                    if (result == 0x00) {
                        if (mViewModel.isRun.get().not()) return@let
                        pause()
                        config.surUseCount.plus(mViewModel.controlLogCat.value!!.count)
                        CacheUtil.setCommonConfig(config)
                        mViewModel.insertLogcat()
                        val customer = act.curCustomerEntity.value ?: return@let
                        pulishMqtt(
                            hashMapOf(
                                "clientdate" to customer.firstTime,
                                "clientname" to customer.name,
                                "clientcontent" to customer.first_treatment_conetnt,
                                "id" to mViewModel.controlLogCat.value!!.id,
                                "area" to mViewModel.guangbanmianji.value,
                                "type" to mViewModel.hint.get(),
                                "rounds" to mViewModel.controlLogCat.value!!.count,
                                "content" to customer.last_treatment_conetnt,
                                "density" to mViewModel.nengliangmidu.value,
                                "frequency" to mViewModel.light.value,
                                "pulsewidth" to config.getMaikuan(mViewModel.selectPS.get()),
                                "wavelength" to (if (mViewModel.select1064.get()) 1064 else 532)
                            )
                        )
                    } else {
                        run()
                        mViewModel.controlLogCat.value =
                            ControlLogCatEntity(
                                Date().getTimeFormat("yyyyMMddhhmmss"),
                                handlerId = act.curHandlerEntity.value?.uid ?: -1,
                                customerId = act.curCustomerEntity.value?.uid ?: 0,
                                handlerName = act.curHandlerEntity.value?.name ?: "admin",
                                zhijing = mViewModel.guangbanmianji.value.toString(),
                                pinglv = mViewModel.light.value.toString(),
                                bochang = (if (mViewModel.select1064.get()) 1064 else 532).toString(),
                                shoujuType = mViewModel.hint.get(),
                                midu = mViewModel.nengliangmidu.value.toString(),
                                maikuan = config.getMaikuan(mViewModel.selectPS.get())
                                    .toString(),
                                treatment_conetnt = mViewModel.curCustomerEntity.value!!.last_treatment_conetnt
                            )
                    }
                }
                //手具检测
                0x26 -> {
                    showOtherShouju(result)
                    if (yunguangshouju.containsKey(result)) {
                        mViewModel.hint.set("匀光手具")
                        mViewModel.guangbanmianji.value = yunguangshouju[result] ?: 0
                    } else if (tiaojiaoshouju.contains(result)) {
                        mViewModel.hint.set("调焦手具")
                        mViewModel.guangbanmianji.value = tiaojiaoshouju[result] ?: 0
                    }

                    mViewModel.nengliangmidu.value =
                        if (mViewModel.guangbanmianji.value > 0)
                            (4 * mViewModel.mJ.value).div(31.4f * mViewModel.guangbanmianji.value)
                        else
                            0f
                    if (step != 0) return@let
                    lifecycleScope.launch(Dispatchers.Main) {
                        sendVolt()
                        delay(100)
                        SerialPortUtil.sendSerialPort(
                            CommondData.getInstance()
                                .makeMode(config.getRealMode().toByte())
                        )
                        delay(100)
                        SerialPortUtil.sendSerialPort(
                            CommondData.getInstance()
                                .makeFreqL(mViewModel.light.value.toByte())
                        )
                        delay(100)
                        SerialPortUtil.sendSerialPort(
                            CommondData.getInstance()
                                .makeWave(if (mViewModel.select1064.get()) 1 else 0)
                        )
                        delay(100)
                        SerialPortUtil.sendSerialPort(
                            CommondData.getInstance()
                                .makeTime(config.getRealTime(0), config.getRealTime(1))
                        )
                        step++
                        mViewModel.isReady.set(true)
                    }

                }
                //故障
                0xD1 -> {
                    mViewModel.errorHint.set(errorVolt[result - 1])
                }
                0xD2 -> {
                    mViewModel.errorHint.set(errorSJ[result - 1])
                }
                0xD3 -> {
                    mViewModel.errorHint.set(errorWD[result - 1])
                }
                0xD4 -> {
                    if (result == 0x01)
                        mViewModel.errorHint.set("水流故障")
                }
                0xD5 -> {
                    if (result <= 0x02)
                        mViewModel.errorHint.set("门开关故障")
                }
                0xD6 -> {
                    if (result >= 0x04)
                        mViewModel.errorHint.set("水温过高")
                    else if (result <= 0x02)
                        mViewModel.errorHint.set("水温过低")
                }
                0xD7 -> {
                    if (result <= 0x01)
                        mViewModel.errorHint.set("水位过低")
                }
                0xD8 -> {
                    if (result == 0x01)
                        mViewModel.errorHint.set("水质差")
                }
                else -> {
                }
            }
        }
    }

    private fun pulishMqtt(map: HashMap<String, Any>) {
        MyMqttService.publish(map.toJson())
    }

    override fun lazyLoadData() {
        SerialPortUtil.sendSerialPort(CommondData.CHECK)
    }

    override fun createObserver() {
        super.createObserver()
        act.controlLogCat.observe(this) {
            it ?: return@observe
            mViewModel.light.value = it.pinglv.toIntOrNull() ?: 1
            mViewModel.select1064.set(it.bochang.toIntOrNull() == 1064)
        }
        act.curHandlerEntity.observe(this) {
            it?.let {
                mViewModel.handlername.set(it.name)
            }
        }
        act.curCustomerEntity.observe(this) {
            it?.let {
                mViewModel.curCustomerEntity.postValue(it)
            }
        }
        mViewModel.mJ.observe(this) {
            sendVolt()
            mViewModel.nengliangmidu.value =
                if (mViewModel.guangbanmianji.value > 0)
                    (4 * it).div(31.4f * mViewModel.guangbanmianji.value)
                else
                    0f
        }
    }

    private fun getCount(it: IntArray): Int {
        return it[2].shl(8 * 3) + it[3].shl(8 * 2) + it[4]
            .shl(8 * 1) + it[5]
    }

    private fun showOtherShouju(type: Int) {
        when (type) {
            0x0b -> {
                iv_center.isVisible = true
                btn_bottom.isVisible = true
                group_center.isInvisible = true
                iv_center.setImageResource(R.drawable.fengchaoshouju)
                mViewModel.select1064.set(true)
                mViewModel.hint.set("1064nm\n蜂巢手具")
            }
            0x0d -> {
                iv_center.isVisible = true
                btn_bottom.isVisible = true
                group_center.isInvisible = true
                iv_center.setImageResource(R.drawable.ranliaoshouju)
                mViewModel.select1064.set(false)
                mViewModel.hint.set("650nm\n燃料手具")
            }
            0x0c -> {
                iv_center.isVisible = true
                btn_bottom.isVisible = true
                group_center.isInvisible = true
                iv_center.setImageResource(R.drawable.ranliaoshouju)
                mViewModel.select1064.set(true)
                mViewModel.hint.set("585nm\n燃料手具")
            }
            else -> {
                iv_center.isVisible = false
                btn_bottom.isVisible = false
                group_center.isInvisible = false
            }
        }

    }

    inner class Click {

        fun gotoLogCat() {
            mViewModel.curCustomerEntity.value.notNull({
                it as CustomerEntity
                nav().navigate(R.id.controlLogCatFragment, bundleOf("userId" to it.uid))
            }, {
                mannger()
            })

        }

        fun nextStep() {
            if (mViewModel.isReady.get()) {
                when (step) {
                    1 -> {
                        if (mViewModel.curCustomerEntity.value != null)
                            SerialPortUtil.sendSerialPort(CommondData.YU_RAN_START)
                        else
                            ToastUtils.showShort("请先添加客户")
                    }
                    2 -> stop()
                }
            }
        }

        fun ps() {
            if (step != 1) {
                return
            }
            mViewModel.timeText.set(config.getPimiaoTitle())
        }

        fun ns() {
            if (step != 1) {
                return
            }
            mViewModel.timeText.set(config.getNamiaoTitle())
        }


        fun set1064() {
            if (step != 1) {
                return
            }
            SerialPortUtil.sendSerialPort(CommondData.getInstance().makeWave(1))
            mViewModel.select1064.set(true)
            sendVolt()
        }


        fun set532() {
            if (step != 1) {
                return
            }
            SerialPortUtil.sendSerialPort(CommondData.getInstance().makeWave(0))
            mViewModel.select1064.set(false)
            mViewModel.mJ.apply {
                if (value > 250)
                    postValue(250)
            }
            sendVolt()
        }

        fun back() {
            goBackHome = false
            ToastUtils.showShort("准备断开")
            SerialPortUtil.sendSerialPort(CommondData.STOP_CONTROL)
        }

        fun home() {
            goBackHome = true
            ToastUtils.showShort("准备断开")
            SerialPortUtil.sendSerialPort(CommondData.STOP_CONTROL)
        }

        fun mannger() {
            nav().goMannger()
        }

        fun exit() {
            exitProcess(0)
        }

        fun plus_light() {
            if (step != 1) {
                return
            }
            mViewModel.light.apply {
                if (value < config.getRealHighestHz()) {
                    postValue(++value)
                    SerialPortUtil.sendSerialPort(
                        CommondData.getInstance().makeFreqL(value.toByte())
                    )
                }
            }
        }

        fun minus_light() {
            if (step != 1) {
                return
            }
            mViewModel.light.apply {
                if (value > 1) {
                    postValue(--value)
                    SerialPortUtil.sendSerialPort(
                        CommondData.getInstance().makeFreqL(value.toByte())
                    )
                }
            }
        }


        fun plus_mJ() {
            if (step != 1) {
                return
            }
            mViewModel.mJ.apply {
                val max = if (mViewModel.select1064.get()) 450 else 200
                if (value in 50..max)
                    postValue(value + 50)
            }
        }

        fun minus_mJ() {
            if (step != 1) {
                return
            }
            mViewModel.mJ.apply {
                if (value in 100..500)
                    postValue(value - 50)
            }
        }

        fun setting() {
            nav().navigate(R.id.settingFragment)
        }

        fun hongmiao() {
            group_hongmiao.apply {
                isVisible = isVisible.not()
            }
        }

        fun setIsCountDown(isCountDown: Boolean) {
            if (mViewModel.isYuran.get().not()) {
                if (mViewModel.isCountDown.get()) {
                    et_dancijishu_num.isVisible = isCountDown
                }
                mViewModel.isCountDown.set(isCountDown)
                tv_dancijishu_num.isVisible = et_dancijishu_num.isVisible.not()
            }
        }

        fun save() {

        }
    }

    private fun sendVolt() {
        SerialPortUtil.sendSerialPort(
            CommondData.getInstance().makeVolt(
                config.getRealVolt(
                    if (mViewModel.select1064.get()) 0 else 1,
                    mViewModel.mJ.value
                ).times(config.jiaozhunxishu.get()).toInt(),
                config.getRealVolt(
                    if (mViewModel.select1064.get()) 2 else 3,
                    mViewModel.mJ.value
                ).times(config.jiaozhunxishu.get()).toInt()
            )
        )
    }

    private fun yuran() {
        center_btn.setBackgroundResource(R.drawable.run_bg)
        iv_center.isSelected = true
        btn_bottom.isSelected = true
        mViewModel.centerHint.set("运行")
        step++
    }

    private fun run() {
        if (mViewModel.isYuran.get()) {
            mViewModel.isRun.set(true)
            mViewModel.centerHint.set("运行中")
        }
    }

    private fun pause() {
        if (mViewModel.isYuran.get()) {
            mViewModel.isRun.set(false)
            mViewModel.centerHint.set("运行")
        }
    }

    private fun stop() {
        if (mViewModel.isYuran.get() && mViewModel.isRun.get().not()) {
            SerialPortUtil.sendSerialPort(CommondData.YU_RAN_STOP)
        }
    }

    private fun stopRun() {
        SerialPortUtil.sendSerialPort(CommondData.RUN_STOP)
    }

    private fun finishStop() {
        mViewModel.centerHint.set("准备")
        center_btn.setBackgroundResource(R.drawable.ready_bg)
        iv_center.isSelected = false
        btn_bottom.isSelected = false
        step = 1
        mViewModel.runCount.set(mViewModel.count)
    }
}